﻿using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using HiSport.Application.Service.Function.ReserveSiteManagement.Service;
using HiSport.Application.Service.Order.OrderSite.Dtos;
using HiSport.Application.Service.OrderManage.OrderFixeSite.Dtos;
using HiSport.Core;
using HiSport.Core.Entity;
using HiSport.Core.Entity.HiSportEntity.Bas;
using HiSport.Core.Entity.Order;
using HiSport.Core.Util;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yitter.IdGenerator;
using static HiSport.Application.Service.Function.ReserveSiteManagement.Dtos.SiteDto;
using static HiSport.Application.Service.OrderManage.OrderFixeSite.Dtos.OrderFixeSiteDto;

namespace HiSport.Application.Service.OrderManage.OrderFixeSite.Service
{
    //[ApiDescriptionSettings("订单管理", Tag = "固定订场订单管理", SplitCamelCase = false)]
    [ApiDescriptionSettings("OrderManage", Tag = "OrderFixeSite", SplitCamelCase = false)]
    public class OrderFixeSiteService : ITransient, IDynamicApiController, IOrderFixeSiteService
    {
        /// <summary>
        /// 订单主表
        /// </summary>
        private readonly SqlSugarRepository<Core.Entity.Order.OrderFixeSite> _orderFixeSite;

        private readonly SqlSugarRepository<SysMember> _sysMember;

        /// <summary>
        /// 订单子表
        /// </summary>
        private readonly SqlSugarRepository<OrderFixeSiteInfo> _orderFixeSiteInfo;

        private readonly IScheduledSiteService _reserveSiteService;

        public OrderFixeSiteService(SqlSugarRepository<HiSport.Core.Entity.Order.OrderFixeSite> orderFixeSite,
            SqlSugarRepository<OrderFixeSiteInfo> _orderFixeSiteInfo,
            SqlSugarRepository<SysMember> sysMember,
            IScheduledSiteService reserveSiteService)
        {
            _orderFixeSite=orderFixeSite;
            this._orderFixeSiteInfo = _orderFixeSiteInfo;
            _reserveSiteService=reserveSiteService;
            _sysMember=sysMember;
        }

        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        public async Task<SqlSugarPagedList<OrderFixeSiteDto>> Page(OrderFixeSitePageDto inputDto)
        {
            var memberId = await _sysMember.AsQueryable()
                .Where(x => x.Name.Contains(inputDto.MemberInfo))
                .Select(x => x.Id)
                .ToListAsync();

            var result = await _orderFixeSite.AsQueryable()
                .LeftJoin<BasSiteType>((x,y)=>x.SiteTypeId==y.Id)
                .WhereIF(inputDto.SiteTypeId.HasValue, (x, y) => x.SiteTypeId==inputDto.SiteTypeId)
                .WhereIF(inputDto.OrderState.HasValue, (x, y) => x.OrderState==inputDto.OrderState)
                .WhereIF(inputDto.FixeSiteStartTime.HasValue, (x, y) => x.FixeSiteStartTime==inputDto.FixeSiteStartTime)
                .WhereIF(inputDto.FixeSiteEndTime.HasValue, (x, y) => x.FixeSiteEndTime == inputDto.FixeSiteEndTime)
                .WhereIF(!string.IsNullOrEmpty(inputDto.MemberInfo), (x, y) =>
                    x.Phone.Contains(inputDto.MemberInfo) || memberId.Contains(x.MemberId))
                .OrderBy((x, y) => x.FixeSiteEndTime, OrderByType.Desc)
                .Select((x, y) => new OrderFixeSiteDto()
                {
                    Id = x.Id.SelectAll(),
                    SiteTypeName=y.SiteTypeName
                })
                .ToPagedListAsync(inputDto.Page, inputDto.PageSize);

            var ids= result.Items.Select(x=>x.Id).ToList();

            var  dataInfo=await _orderFixeSiteInfo.AsQueryable().Where(x=>ids.Contains(x.OrderFixeSiteId)).ToListAsync();

            foreach (var item in result.Items)
            {
                var thisDataInfo= dataInfo.Where(x => x.OrderFixeSiteId == item.Id)
                    .Select(x => new OrderFixeSiteInfoDto()
                    {
                        Id = x.Id.SelectAll(),
                    })
                    .ToList();

                item.OrderFixeSiteInfos = thisDataInfo;
                item.TotalCount = dataInfo.Count;
                item.CompleteCount = dataInfo.Where(x=>x.OrderState==OrderStateEnum.Complete).Count();
            }

            return result;
        }

        /// <summary>
        /// 创建 固定订场订单
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        [UnitOfWork]
        [ApiDescriptionSettings(Name = "Create"), HttpPost]
        [DisplayName("创建固定订场订单")]
        public async Task<long> Create(FixedOrderSiteCreateOrUpdateDto inputDto)
        {
            //1.创建主订单
            var orderData = inputDto.Adapt<Core.Entity.Order.OrderFixeSite>();
            orderData.OrderNum = FunctionUtil.GetOrderNum(OrderNumType.GD);
            orderData.Id = YitIdHelper.NextId();
            await _orderFixeSite.InsertAsync(orderData);

            //2.新建子订单
            var orderDataInfos = new List<OrderFixeSiteInfo>();

            //时间
            while (inputDto.FixedStartTime.Date<= inputDto.FixedEndTime.Date)
            {
                var thisWeek = inputDto.FixedStartTime.DayOfWeek;
                //场次
                foreach (var info in inputDto.FixedOrderSiteInfos)
                {
                    if (info.WeekList.Contains(thisWeek))
                    {
                        //场地
                        foreach (var siteId in info.SiteIds)
                        {
                            //时间
                            foreach (var time in info.ScheduledTimes)
                            {

                                orderDataInfos.Add(new OrderFixeSiteInfo()
                                {
                                    EndTime= time.EndTime, 
                                    StartTime= time.StartTime,
                                    SiteId=siteId,
                                    FixeSiteScheduledTime= inputDto.FixedStartTime.Date,
                                    PayType= PayTypeEnum.Unknown,
                                    ActualPayAmount=0,
                                    DiscountAmount=0,
                                    OrderFixeSiteId= orderData.Id,
                                    OrderPayState=OrderPayStateEnum.Unpaid,
                                    TotalAmount=0,
                                    ScheduledSiteState= ScheduledSiteStateEnum.FixedUnpaid,
                                    OrderState=OrderStateEnum.Afoot,
                                });
                            }
                        }
                    }
                }

                inputDto.FixedStartTime = inputDto.FixedStartTime.AddDays(1);
            }

            //验证场地是否可以预定
            await _reserveSiteService.SiteCheck(orderDataInfos.Select(x => new SiteCheckDto()
            {
                EndTime = x.EndTime,
                SiteId = x.SiteId,
                StartTime = x.StartTime,
                Time = x.FixeSiteScheduledTime
            }).ToList());

            await _orderFixeSiteInfo.InsertRangeAsync(orderDataInfos.ToArray());

            return orderData.Id;
        }

        /// <summary>
        /// 修改 固定场地订单(已完成的 无法修改)
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        [UnitOfWork]
        [ApiDescriptionSettings(Name = "Update"), HttpPost]
        [DisplayName("修改 固定场地订单")]
        public async Task<bool> Update(FixedOrderSiteCreateOrUpdateDto inputDto)
        {
            //1.查询主订单
            var orderData=await _orderFixeSite.AsQueryable().Where(x=>x.Id==inputDto.Id).FirstAsync();


            //2.查询子订单 (完成订单修改不了)
            var orderDataInfo = await _orderFixeSiteInfo.AsQueryable()
                .Where(x => x.OrderFixeSiteId == orderData.Id&&x.OrderState== OrderStateEnum.Complete)
                .ToListAsync();

            //3.删除订单
           await  _orderFixeSiteInfo.FakeDeleteAsync(orderDataInfo);

            //4.添加新订单
            var orderDataInfos = new List<OrderFixeSiteInfo>();

            //时间
            while (inputDto.FixedStartTime.Date <= inputDto.FixedEndTime.Date)
            {
                var thisWeek = inputDto.FixedStartTime.DayOfWeek;
                //场次
                foreach (var info in inputDto.FixedOrderSiteInfos)
                {
                    if (info.WeekList.Contains(thisWeek))
                    {
                        //场地
                        foreach (var siteId in info.SiteIds)
                        {
                            //时间
                            foreach (var time in info.ScheduledTimes)
                            {

                                orderDataInfos.Add(new OrderFixeSiteInfo()
                                {
                                    EndTime = time.EndTime,
                                    StartTime = time.StartTime,
                                    SiteId = siteId,
                                    FixeSiteScheduledTime = inputDto.FixedStartTime.Date,
                                    PayType = PayTypeEnum.Unknown,
                                    ActualPayAmount = 0,
                                    DiscountAmount = 0,
                                    OrderFixeSiteId = orderData.Id,
                                    OrderPayState = OrderPayStateEnum.Unpaid,
                                    TotalAmount = 0,
                                    ScheduledSiteState = ScheduledSiteStateEnum.FixedUnpaid,
                                    OrderState = OrderStateEnum.Afoot,
                                });
                            }
                        }
                    }
                }

                inputDto.FixedStartTime = inputDto.FixedStartTime.AddDays(1);
            }

            //验证场地是否可以预定
            await _reserveSiteService.SiteCheck(orderDataInfos.Select(x => new SiteCheckDto()
            {
                EndTime = x.EndTime,
                SiteId = x.SiteId,
                StartTime = x.StartTime,
                Time = x.FixeSiteScheduledTime
            }).ToList());

            await _orderFixeSiteInfo.InsertRangeAsync(orderDataInfos.ToArray());


            return true;
        }

        /// <summary>
        /// 取消 固定订场
        /// </summary>
        /// <returns></returns>
        [UnitOfWork]
        [DisplayName("修改 固定场地订单")]
        public async Task<bool> CancelFixedOrderSite(string orderNum)
        {
            var data =await _orderFixeSite.GetFirstAsync(x => x.OrderNum == orderNum);
            if (data == null)
            {
                throw Oops.Oh($"【{orderNum}】没有查询到订单信息");
            }
            data.OrderState = OrderStateEnum.AllCancel;
            await _orderFixeSite.UpdateAsync(data);

            var dataInfos =await _orderFixeSiteInfo.GetListAsync(x => x.OrderFixeSiteId == data.Id);
            if (dataInfos.Count() <= 0)
            {
                throw Oops.Oh($"【{orderNum}】订单没有固定订场信息");
            }
            dataInfos.Select(x => x.OrderState == OrderStateEnum.AllCancel);
            await _orderFixeSiteInfo.UpdateRangeAsync(dataInfos);

            return true;
        }
    }
}
    
